%{
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#define YYSTYPE double

int yylex(void);
void yyerror(char const*);
%}
%token NUM
/* 行号越大，优先级越高 */
%left '+' '-'
%left '*' '/'
%left NEG /* 负号 */
%right '^' /* 幂运算 */
%%
input:/* empty */
	| input line
;
line:	'\n'
	| num '\n' { printf("num = %lf\n",$1); }
	| error '\n' { yyerrok; }/* 错误报告 */
;
num:	NUM
	|num '+' num { $$ = $1 + $3; }
	| num '-' num { $$ = $1 - $3; }
	| num '*' num { $$ = $1 * $3; }
	| num '/' num 
		{
			if($3)
			{
				$$ = $1 / $3;
			}
			else
			{
				$$ = 1;
				// @n 代表第n个组件，@3为yylloc
				fprintf(stderr,"%d.%d-%d.%d:division by zero\n",
					@3.first_line,@3.first_column,@3.last_line,@3.last_column);
			}
			
		}
	| '-' num %prec NEG { $$ = $2; }
	| num '^' num { $$ = pow($1,$3)}
	| '(' num ')' { $$ = $2; }
;
%%
int main(void)
{
	yylloc.first_line = yylloc.last_line = 1;
	yylloc.first_column = yylloc.last_column = 0;
	return yyparse();
}
void yyerror(char const* s)
{
	printf("err => %s\n",s);
}
int yylex(void)
{
	char c;
	while((c = getchar()) == ' ' || c == '\t')
		++yylloc.last_column;// yylloc记录位置信息的全局变量
	if(isdigit(c) || c == '.')
	{
		yylval = c - '0';
		++yylloc.last_column;
		while(isdigit(c = getchar()))
		{
			++yylloc.last_column;
			yylval = yylval * 10 + (c - '0');
		}
		ungetc(c,stdin);
		// scanf("%lf",&yylval);
		return NUM;
	}
	if(c == '\n')
	{
		++yylloc.last_line;
		yylloc.last_column = 0;
	}
	else
	{
		++yylloc.last_column;
	}
	return c;
}
